package datastructure.map;

import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

/**
 * @author TaoTaojs
 * @date 2021/2/25 上午8:55
 * <p>Description</p>
 * <h2>功能描述</h2>
 * 测试ConcurrentMap的线程安全
 * <h3>主要功能：</h3>
 * <ol>
 *     <li></li>
 * </ol>
 * <h3>关联类</h3>
 * <p>参考链接：</p>
 * <h2>更新日志</h2>
 * [author]        [time]                      [version]          [desc]
 * TaoTaojs        2021/2/25 上午8:55             V1.0
 */
@SuppressWarnings("ALL")
public class ConcurrentHashMapDemo {

    private static final int ITEM_COUNT = 1000;
    private static final int THREAD_COUNT = 10;

    private Random random = new Random(10000);

    private ConcurrentHashMap<String, Long> concurrentHashMap = getData(ITEM_COUNT - 100);
    private ConcurrentHashMap<String, Long> concurrentHashMap2 = new ConcurrentHashMap<>(ITEM_COUNT);

    public static void main(String[] args) throws InterruptedException {
        ConcurrentHashMapDemo concurrentHashMapDemo = new ConcurrentHashMapDemo();
//        concurrentHashMapDemo.是否为线程安全();
        concurrentHashMapDemo.使用ComputeIfAbsent();
    }

    public void 是否为线程安全() throws InterruptedException {
        System.out.println("init size: " + concurrentHashMap.size());
        ForkJoinPool forkJoinPool = new ForkJoinPool(THREAD_COUNT);
        forkJoinPool.execute(() -> {
            IntStream.rangeClosed(1,10).parallel().forEach(e -> {
//                synchronized (concurrentHashMap) {
                int gap = ITEM_COUNT - concurrentHashMap.size();
                System.out.println("gap size:" + gap);
                concurrentHashMap.putAll(getData(gap));
//                }
            });
        });
        forkJoinPool.shutdown();
        forkJoinPool.awaitTermination(1, TimeUnit.HOURS);

        System.out.println("finish size:" + concurrentHashMap.size());
    }

    public void 使用ComputeIfAbsent() throws InterruptedException {
        System.out.println("init size: " + concurrentHashMap2.size());
        ForkJoinPool forkJoinPool = new ForkJoinPool(THREAD_COUNT);
        forkJoinPool.execute(() -> {
            IntStream.rangeClosed(1, ITEM_COUNT).parallel().forEach(e -> {
                String key = "item" + ThreadLocalRandom.current().nextLong(ITEM_COUNT);
                concurrentHashMap2.computeIfAbsent(key, k -> ThreadLocalRandom.current().nextLong(ITEM_COUNT)).doubleValue();
            });
        });
        forkJoinPool.shutdown();
        forkJoinPool.awaitTermination(1, TimeUnit.HOURS);

        System.out.println("finish size:" + concurrentHashMap2.size());
    }

    public ConcurrentHashMap getData(int size){
        ConcurrentHashMap map = new ConcurrentHashMap<>();
        for (int i = 0; i < size; i++) {
            map.put(System.currentTimeMillis() + "--" + random.nextInt(), 1);
        }
        return map;
    }


}
